O ray tracing é uma técnica de síntese de imagens fotorealísticas.
def raytracing( ): ''' Gerar uma imagem '''
''' para cada pixel x, y do viewport
cor(pixel) = trace( raio_atraves_posicao_(x,y) )
def trace( raio ):
pontoObjeto = intersection( raio )
if [ pontoObjeto ]:
shade( pontoObjeto, raio );
else:
retorne cor de fundo
def intersection( raio ):
para cada objeto na cena
calcular intersecao( raio, objeto )
retorne o ponto de intersecao calculado
''' pode retornar informações sobre a normal da superficie,
propriedades do material, etc. '''
def shade( point, raio ):
calcula o vetor normal da superficie e usa a formula de
Phong da iluminação ( ou similar ) para calcular as contribuições
de cada fonte de luz.
Um raio com a origem em $\vec{R_{0}}$ e o vetor diretor dada por $\vec{R_{d}}$ e adotando t como parâmetro da descrição paramétrica da reta. Podemos representar a reta através da equação:
Como $\vec{R_{d}} = [x(1)-x(0), y(1)-y(0), z(1)-z(0)] = [d_{x}, d_{y}, d_{z}]$, $\vec{R(t)} = [x(t), y(t), z(t)]$ e $\vec{R_{0}} = [x(0), y(0), z(0)]$ substituímos na equação acima para obtermos um sistema de equações as quais representam o raio.
Seja $S_{c}$ o centro da esfera de coordenadas $[x_{c}, y_{c}, z_{c}$] e $S_{s}$ um ponto qualquer da superfície esférica cujas coordenadas são $[x, y, z$]. A superfície da esfera é o lugar geométrico dos pontos que satisfaz a seguinte equação, onde r é o raio da esfera:
$\midS_{s} - S_{c}\mid - r = 0$
Desenvolvendo a equação acima encontramos a seguinte equação:
$(x - x_{c})^2 + (y - y_{c})^2 + (z - z_{c})^2 - r^2 = 0$
$x^2 - 2x_{c}x + x_{c}^2 + y^2 - 2y_{c}y + y_{c}^2 + z^2 - 2z_{c}z + z_{c}^2 = r^2$
Após a união das equações paramétricas obteremos a seguinte equação:
$x_{0}^2 + 2x_{0}x_{d}t + x_{d}^2t^2 - 2x_{c}(x_{0} + x_{d}t) + x_{c}^2 + y_{0}^2 + 2y_{0}y_{d}t + y_{d}^2t^{2} - 2y_{c}(y_{0} + y_{d}t) + y_{c}^2 + z_{0}^2 + 2z_{0}z_{d}t + z_{d}^2t^2 - 2z_{c}(z_{0} + z_{d}t) + z_{c}^2 = r^2$
Reagrupando os termos, obtemos:
$t^2(x_{d}^2 + y_{d}^2 + z_{d}^2) + 2t[x_{d}(x_{0} - x_{c}) + y_{d}(y_{0} - y_{c}) + z_{d}(z_{0} - z_{c})] + (x_{0} - x_{c})^2 + (y_{0} - y_{c})^2 + (z_{0} - z_{c})^2 = r^2$
Obtemos assim uma equação de segundo grau em relação a t:
$At^2 - 2Bt + C = 0$
onde os termos A, B e C são:
$A=x_{d}^2 + y_{d}^2 + z_{d}^2$
$B=x_{d}(x_{c} - x_{0}) + y_{d}(y_{c} - y_{0}) + z_{d}(z_{c} - z_{0})$
$C=(x_{c} - x_{0})^2 + (y_{c} - y_{0})^2 + (z_{c} - z_{0})^2 - r^2$
Se o vetor $\vec{R_{d}}$ for um vetor unitário, ou seja, ($\mid{R_{d}\mid = 1$) então $A=1$. Desta forma, podemos simplificar para equações de segundo grau:
$\Delta = B^2 - 4C$
$t = \frac{-B \pm \sqrt{\Delta}}{2}$
O ponto de interseção entre o raio e a esfera é determinado pela equação:
$\vec{R_{i}} = [x_{0} + x_{d}t, y_{0} + y_{d}t, z_{0} + z_{d}t]$
Dado $\vec{R_{i}} = [x_{i}, y_{i}, z_{i}]$ o vetor da posição de interseção entre raio e a esfera, podemos obter a normal a superfície com a seguinte equação:
$\vec{n_{i}} = \Big[\frac{x_{i} - x_{c}}{\mid [x_{i} - x_{c}, y_{i} - y_{c}, z_{i} - z_{c}] \mid}, \frac{y_{i} - y_{c}}{\mid [x_{i} - x_{c}, y_{i} - y_{c}, z_{i} - z_{c}] \mid}, \frac{z_{i} - z_{c}}{\mid [x_{i} - x_{c}, y_{i} - y_{c}, z_{i} - z_{c}] \mid} \Big]$
Se $\vec{x}$ é algum ponto do plano, então o vetor $\vec{x} - \vec{x_{0}}$ é ortogonal ao vetor normal ($\vec{n} = (A, B, C)$):
$\vec{n} . (\vec{x} - \vec{x_{0}}) = 0$
$(A, B, C) . (\vec{x} - \vec{x_{0}}) = 0$
Sejam $\vec{x} = (x, y, z)$ e $\vec{x_{0}} = (x_{0}, y_{0}, z_{0})$ substituimos na equação acima para obtermos:
$(A, B, C) . ( x - x_{0}, y - y_{0}, z - z_{0} ) = 0$
$A(x - x_{0}) + B(y - y_{0}) + C(z - z_{0}) = 0$
Reorganizando a expressão acima podemos reescrever da seguinte forma:
$Ax + By + Cz + D = 0$
Após a união das equações do raio e do plano obtemos:
$A(x_{0} + x_{d}t) + B(y_{0} + x_{d}t) + C(z_{0} + z_{d}t) + D = 0$
Se isolarmos o t obteremos o ponto de interseção entre o raio e o plano:
$t = -\frac{Ax_{0}+By_{0}+Cz_{0}+D}{Ax_{d}+By_{d}+Cz_{d}}$
que em notação vetorial pode ser expressa como:
$t = -\frac{\vec{n}.\vec{R_{0}} + D}{\vec{n}.\vec{R_{d}}}$
Para análise da interseção basta verificarmos o valor do denominador da expressão acima.
O ponto de interseção entre o raio e o plano é determinado pela equação:
$\vec{R_{i}} = [x_{0} + x_{d}t, y_{0} + y_{d}t, z_{0} + z_{d}t]$
Seja $\vec{l} = [l_{x}, l_{y}, l_{z}]$ a posição da fonte de luz, $\vec{N} = [n_{x}, n_{y}, n_{z}]$ é o vetor normal e $\vec{R_{i}} = [x_{i}, y_{i}, z_{i}]$ o vetor da posição de interseção, temos: